package com.example.java_gobang.api.controller;

import com.example.java_gobang.game.dto.MatchRequest;
import com.example.java_gobang.game.vo.MatchResponse;
import com.example.java_gobang.game.service.Matcher;
import com.example.java_gobang.game.service.OnlineUserManager;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Slf4j
@Component
public class MatchAPI extends TextWebSocketHandler {

    private final ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 玩家上线，将玩家加入到 OnlineUserManager 中
        try {
            // 1.获取当前用户身份信息
            User user = (User) session.getAttributes().get("user");

            // 2.判断当前用户是否已经在其他地方登陆了
            if (onlineUserManager.getFromGameHall(user.getUserId()) != null || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                MatchResponse matchResponse = new MatchResponse();
                matchResponse.setOk(true);
                matchResponse.setReason("用户已在其它地方登陆");
                matchResponse.setMessage("repeatConnection");
                session.sendMessage(new TextMessage(mapper.writeValueAsString(matchResponse)));
                // session.close();
                return;
            }

            // 3.将玩家设置为在线状态
            onlineUserManager.enterGameHall(user.getUserId(), session);
            log.info("玩家：{} 进入游戏大厅", user.getUserId());
        } catch (NullPointerException e) {
            e.printStackTrace();
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("您尚未登录！不能进行后续匹配功能！");
            session.sendMessage(new TextMessage(mapper.writeValueAsString(response)));
        }

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理 开始匹配 和 匹配停止 的请求
        User user = (User) session.getAttributes().get("user");
        // 获取客户端发给服务端的数据
        String payload = message.getPayload();
        // 接收JSON格式字符串
        MatchRequest request = mapper.readValue(payload, MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {
            // 进入匹配队列
            // 创建匹配队列，将玩家添加进去
            matcher.add(user);
            response.setOk(true);
            response.setMessage("startMatch");
        } else if (request.getMessage().equals("stopMatch")) {
            // 退出匹配队列
            matcher.remove(user);
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            // 非法情况
            response.setOk(false);
            response.setMessage("非法匹配请求 ");
        }
        session.sendMessage(new TextMessage(mapper.writeValueAsString(response)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        // 玩家下线，从 OnlineUserManager 删除玩家
        try {
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(user.getUserId());
            }

            // 从匹配队列移除
            log.warn("玩家: {} 掉线", user.getUserId());
            matcher.remove(user);
        } catch (NullPointerException e) {
            log.warn("当前用户尚未登录！不能进行后续匹配功能！");
            log.warn("{}", e.getMessage());

//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录！不能进行后续匹配功能！");
//            session.sendMessage(new TextMessage(mapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        // 玩家下线，从 OnlineUserManager 删除玩家
        try {
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(user.getUserId());
            }

            // 从匹配队列移除
            log.warn("玩家: {} 下线", user.getUserId());
            matcher.remove(user);
        } catch (NullPointerException e) {
            log.warn("当前用户尚未登录！不能进行后续匹配功能！");
            log.warn("{}", e.getMessage());

//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("您尚未登录！不能进行后续匹配功能！");
//            session.sendMessage(new TextMessage(mapper.writeValueAsString(response)));
        }
    }
}
